#include "Blocks/DoorBlock.h"
#include "GameSingleton.h"
#include "Subsystems/SubsystemTerrain.h"
#include "Managers/BlocksManager.h"
#include "Components/ComponentMiner.h"
#include "Components/ComponentCreature.h"
#include "Components/ComponentCreatureModel.h"

using namespace PocketSurvival::Engine;

namespace PocketSurvival
{

    DoorBlock::DoorBlock()
    {
        addInheritance(this);
    }

    void DoorBlock::initialize()
    {
        m_subsystemTerrain = GameSingleton::singletonPtr->getSingleton<SubsystemTerrain>();
    }

    BlockPlacementData DoorBlock::getPlacementValue(ComponentMiner *componentMiner, int32_t value, const TerrainRaycastResult &raycastResult)
    {
        Vector3 forward = componentMiner->componentCreature->componentCreatureModel->getEyeRotation().toMatrix().getForward();

        float numBuff[4] = {
            Vector3::Dot(forward, FastVector3::UnitZ),
            Vector3::Dot(forward, FastVector3::UnitX),
            Vector3::Dot(forward, FastVector3::DecUnitZ),
            Vector3::Dot(forward, FastVector3::DecUnitX)};
        uint32_t targetIndex = MathUtils::MaxIndex<float>(numBuff, 4);
        int32_t rotation = 0;
        switch (targetIndex)
        {
        case 0:
            rotation = 2;
            break;
        case 1:
            rotation = 3;
            break;
        case 2:
            rotation = 0;
            break;
        case 3:
            rotation = 1;
            break;
        }

        Point3 point = CellFace::FaceToPoint3(raycastResult.cellFace.face);
        int32_t num6 = raycastResult.cellFace.point.posX + point.posX;
        int32_t y = raycastResult.cellFace.point.posY + point.posY;
        int32_t num7 = raycastResult.cellFace.point.posZ + point.posZ;
        bool rightHanded = true;

        switch (rotation)
        {
        case 0:
            rightHanded = GameSingleton::blocksManager->blocks[m_subsystemTerrain->getCellContents(num6 - 1, y, num7)]->IsTransparent;
            break;
        case 1:
            rightHanded = GameSingleton::blocksManager->blocks[m_subsystemTerrain->getCellContents(num6, y, num7 + 1)]->IsTransparent;
            break;
        case 2:
            rightHanded = GameSingleton::blocksManager->blocks[m_subsystemTerrain->getCellContents(num6 + 1, y, num7)]->IsTransparent;
            break;
        case 3:
            rightHanded = GameSingleton::blocksManager->blocks[m_subsystemTerrain->getCellContents(num6, y, num7 - 1)]->IsTransparent;
            break;
        }
        int32_t data = SetRightHanded(SetOpen(SetRotation(0, rotation), false), rightHanded);
        BlockPlacementData result;
        result.value = Terrain::MakeBlockValue(getIndex(), 0, data);
        result.cellFace = raycastResult.cellFace;
        return result;
    }

    bool DoorBlock::IsTopPart(int32_t x, int32_t y, int32_t z)
    {
        int32_t cellContents = GameSingleton::singletonPtr->getSingleton<SubsystemTerrain>()->getCellContents(x, y - 1, z);
        return GameSingleton::blocksManager->blocks[cellContents]->isBlock<DoorBlock *>() == true;
    }

    bool DoorBlock::IsBottomPart(int32_t x, int32_t y, int32_t z)
    {
        int32_t cellContents = GameSingleton::singletonPtr->getSingleton<SubsystemTerrain>()->getCellContents(x, y + 1, z);
        return GameSingleton::blocksManager->blocks[cellContents]->isBlock<DoorBlock *>() == true;
    }

} // namespace PocketSurvival
